Changes for Release 3.7
Release Date: January 7, 2026
Commit Range: 4ebf5faea81788ddba8fac2260d4a06e255ca5e3 β 93ae50a4b19794043534e8b827fa3bd55cb22934
Previous Version: 3.5.0
Release Tags: v3.6.0.0-alpha.1 through v3.7.1.2
Table of Contents
- π Overview
- π Changes Summary
- π Migration Guide
- β Testing Recommendations
- βοΈ Upgrade Checklist
- π Resources
- π Acknowledgments
- π Appendix A: Detailed Commit History
π Overview
Version 3.7 consolidates metric recording infrastructure with filter and enricher patterns, adds .NET 10.0 support, and includes critical bug fixes. This release contains breaking changes to interface naming, configuration properties, and class names.
Key changes:
- Interface rename:
IActivityLoggingSamplerβIActivityLoggingFilter - New naming:
NameBased*βOptionsBased*classes - Added .NET 10.0 target framework support
- Critical fix: Dictionary key duplication exception in v3.7.1.2
- New feature: Multiple named filters and enrichers per metric (v3.7.1.0)
Action required: See Changes Summary and Migration Guide.
π Changes Summary
Release: 3.7.1.2
Type: Breaking Changes
Migration Effort: 5-15 minutes for config-only users, 30-60 minutes for custom implementations
π΄ Breaking Changes
| Category | Old | New | Affected Users | Impact |
|---|---|---|---|---|
| Interface | IActivityLoggingSampler |
IActivityLoggingFilter |
Custom implementations | High |
| Interface | IDiginsightActivitiesMetricOptions |
IMetricRecordingOptions |
Options access | High |
| Interface | ICustomDurationMetricRecorderSettings |
Deleted | Custom metric recorders | High |
| Interface | IDiginsightActivityNamesOptions |
Deleted | Activity name configs | Medium |
| Class | NameBasedActivityLoggingSampler |
OptionsBasedActivityLoggingFilter |
Service registrations | High |
| Class | NameBasedMetricRecordingFilter |
OptionsBasedMetricRecordingFilter |
Service registrations | High |
| Class | DefaultMetricRecordingEnricher |
OptionsBasedMetricRecordingEnricher |
Service registrations | High |
| Property | RecordSpanDurations |
RecordSpanDuration (singular) |
Configuration | Medium |
| Property | Added SpanDurationMeterName |
New property alongside MeterName |
Configuration | Low |
Impact Legend: - High: Immediate action required - code will not compile - Medium: Action required - runtime errors if not updated
- Low: Optional - backward compatibility maintained
Quick Migration Reference:
// Interface changes
// OLD β NEW
IActivityLoggingSampler β IActivityLoggingFilter // β NEW
IDiginsightActivitiesMetricOptions β IMetricRecordingOptions // β NEW
ICustomDurationMetricRecorderSettings β (deleted)
// Class renames
NameBasedActivityLoggingSampler β OptionsBasedActivityLoggingFilter
NameBasedMetricRecordingFilter β OptionsBasedMetricRecordingFilter
DefaultMetricRecordingEnricher β OptionsBasedMetricRecordingEnricherIn descriptions: OldTerm β NewTerm highlights the new syntax.
// Configuration changes
{
"RecordSpanDurations": true, // β Remove (plural)
"RecordSpanDuration": true // β
NEW (singular)
}β¨ Whatβs New
New Features:
Multiple Named Filters and Enrichers (v3.7.1.0) - Configure different filtering and enrichment rules per metric instrument
Use case: When different metrics need different activity filters or tags
Example:
{ "OptionsBasedMetricRecordingFilter:span_duration": { "MetricName": "span_duration", "ActivityNames": { "MyApp.CriticalPath.*": true } }, "OptionsBasedMetricRecordingEnricher:span_duration": { "MetricName": "span_duration", "MetricTags": ["user_id", "tenant_id"] } }
New Interfaces:
IMetricRecordingOptions- ReplacesIDiginsightActivitiesMetricOptionsIOptionsBasedMetricRecordingFilterOptions- Configuration for metric filtersIOptionsBasedMetricRecordingEnricherOptions- Configuration for metric enrichersIActivityLoggingFilter- ReplacesIActivityLoggingSampler
Improvements:
- .NET 10.0 Support: Added
net10.0target framework to all packages - File Structure: Flattened directory structure - moved files from subfolders to root level
- Named Options:
NamedOptionsMonitor<T>andNamedOptions<T>for per-metric configurations - Enricher API: Changed from
IDictionary<string, object?>toTagListfor better performance
π Bug Fixes
Critical:
- Dictionary Key Duplication (v3.7.1.2): Fixed βItem with the same key has already been addedβ exception - See Commit 93ae50a
- Activity Filtering Patterns (v3.7.0.0): Fixed wildcard pattern matching in
OptionsBasedMetricRecordingFilter- See Commit 987638c
Minor:
- DiginsightTextWriter: Improved character escaping and null handling
- Configuration Binding: Fixed configuration binding issues in
DiginsightActivitiesOptions
π Migration Guide
Quick Check: Do You Need to Migrate?
β
No action needed if: - Using default configuration only (no custom code) - Using JSON-based configuration without property RecordSpanDurations (plural) - No custom filter/enricher implementations
β οΈ Action required if:
| Scenario | Old Code | New Code |
|---|---|---|
| Custom sampler implementations | IActivityLoggingSampler |
IActivityLoggingFilter |
| Metric options access | IDiginsightActivitiesMetricOptions |
IMetricRecordingOptions |
| Configuration properties | RecordSpanDurations |
RecordSpanDuration |
| Activity logging sampler registration | NameBasedActivityLoggingSampler |
OptionsBasedActivityLoggingFilter |
| Metric filter registration | NameBasedMetricRecordingFilter |
OptionsBasedMetricRecordingFilter |
| Metric enricher registration | DefaultMetricRecordingEnricher |
OptionsBasedMetricRecordingEnricher |
| Custom metric recorder settings | ICustomDurationMetricRecorderSettings |
Deleted - use IMetricRecordingFilter |
| Activity names configuration | IDiginsightActivityNamesOptions |
Deleted - see migration |
Review each scenario above. If you use any βOld Codeβ pattern, follow the migration steps below.
For Config-Only Users
Estimated time: 5-10 minutes
Step 1: Update Configuration Properties
// OLD - Remove these
{
"Diginsight": {
"Activities": {
"RecordSpanDurations": true // β Remove (plural)
}
}
}
// NEW - Use these
{
"Diginsight": {
"Activities": {
"RecordSpanDuration": true, // β
NEW (singular)
"MeterName": "MyApp", // Optional: general meter name
"SpanDurationMeterName": "MyApp.Spans" // Optional: specific to span metrics
}
}
}Step 2: Test Application
# Run application
dotnet run
# Verify configuration loads without errors
# Check logs for any warnings about deprecated propertiesFor Advanced Users
Estimated time: 30-60 minutes
1. Update Interface Implementations
// OLD - Remove these
public class MyActivityFilter : IActivityLoggingSampler // β Remove
{
public LogBehavior? GetLogBehavior(Activity activity)
{
// Implementation
}
}
// NEW - Use these
public class MyActivityFilter : IActivityLoggingFilter // β NEW interface
{
public LogBehavior? GetLogBehavior(Activity activity)
{
// Same implementation - method signature unchanged
}
}// OLD - Remove these
public class MyEnricher : IMetricRecordingEnricher
{
public void Enrich(Activity activity, IDictionary<string, object?> tags) // β Remove
{
tags["custom"] = "value";
}
}
// NEW - Use these
public class MyEnricher : IMetricRecordingEnricher
{
public void Enrich(Activity activity, TagList tags) // β NEW parameter type
{
tags.Add("custom", "value"); // β NEW API
}
}2. Update Service Registrations
// OLD - Remove these
services.AddSingleton<IActivityLoggingSampler, NameBasedActivityLoggingSampler>(); // β Remove
services.AddSingleton<IMetricRecordingFilter, NameBasedMetricRecordingFilter>(); // β Remove
services.AddSingleton<IMetricRecordingEnricher, DefaultMetricRecordingEnricher>(); // β Remove
// NEW - Use these
services.AddSingleton<IActivityLoggingFilter, OptionsBasedActivityLoggingFilter>(); // β NEW
services.AddSingleton<IMetricRecordingFilter, OptionsBasedMetricRecordingFilter>(); // β NEW
services.AddSingleton<IMetricRecordingEnricher, OptionsBasedMetricRecordingEnricher>(); // β NEW3. Update Options Access
// OLD - Remove these
public class MyService
{
private readonly IDiginsightActivitiesMetricOptions options; // β Remove
public MyService(IDiginsightActivitiesMetricOptions options) // β Remove
{
this.options = options;
bool record = options.RecordSpanDurations; // β Remove (plural)
}
}
// NEW - Use these
public class MyService
{
private readonly IMetricRecordingOptions options; // β NEW interface
public MyService(IMetricRecordingOptions options) // β NEW
{
this.options = options;
bool record = options.Record; // β NEW property name
string meter = options.MeterName; // β NEW property
}
}4. Update Custom Metric Recorders (if using ICustomDurationMetricRecorderSettings)
// OLD - ICustomDurationMetricRecorderSettings interface is deleted
// If you had custom metric recording logic, migrate to:
// NEW - Implement IMetricRecordingFilter instead
public class MyMetricFilter : IMetricRecordingFilter
{
public bool? ShouldRecord(Activity activity, Instrument instrument) // β NEW
{
// Your custom logic here
return true;
}
}
// Register filter
services.AddSingleton<IMetricRecordingFilter, MyMetricFilter>();For New Features (Optional)
Feature: Multiple Named Filters and Enrichers
When to use: When you have multiple custom metrics that need different filtering rules or tags
Example:
// Configuration
{
"OptionsBasedMetricRecordingFilter": {
// Default filter - applies to all metrics if no specific filter
"ActivityNames": {
"MyApp.*": true,
"System.*": false
}
},
"OptionsBasedMetricRecordingFilter:business_metrics": {
// Specific filter for "business_metrics" instrument
"MetricName": "business_metrics",
"ActivityNames": {
"MyApp.Orders.*": true,
"MyApp.Payments.*": true
}
},
"OptionsBasedMetricRecordingEnricher:business_metrics": {
// Specific enricher for "business_metrics" instrument
"MetricName": "business_metrics",
"MetricTags": ["user_id", "tenant_id", "order_type"]
}
}// Service registration (usually automatic via configuration binding)
services.Configure<OptionsBasedMetricRecordingFilterOptions>(
"business_metrics",
configuration.GetSection("OptionsBasedMetricRecordingFilter:business_metrics"));β Testing Recommendations
1. Configuration Loading
// Verify options load correctly
[Fact]
public void Options_LoadCorrectly()
{
var services = new ServiceCollection();
services.AddLogging(builder => builder.AddDiginsightCore());
var sp = services.BuildServiceProvider();
var options = sp.GetRequiredService<IOptions<DiginsightActivitiesOptions>>().Value;
Assert.NotNull(options);
// Test your specific configuration values
}2. Activity Filtering
// Test activity filtering works
[Fact]
public void ActivityFilter_FiltersCorrectly()
{
var filter = new OptionsBasedActivityLoggingFilter(/* dependencies */);
var activity = new Activity("MyApp.TestOperation");
var behavior = filter.GetLogBehavior(activity);
Assert.NotNull(behavior);
}3. Metric Recording
// Test metric recording with named filters
[Fact]
public void MetricRecording_UsesNamedFilter()
{
// Setup with named configuration
var options = new OptionsBasedMetricRecordingFilterOptions
{
MetricName = "test_metric",
ActivityNames = { ["MyApp.*"] = true }
};
var filter = new OptionsBasedMetricRecordingFilter(/* dependencies */);
// Verify filtering works
}βοΈ Upgrade Checklist
π Resources
π Acknowledgments
Contributors: - Filippo Mineo - Core metric recording refactoring, interface redesign, bug fixes - Dario Airoldi - .NET 10.0 support, documentation updates, testing
For questions or issues: GitHub Issues
π Appendix A: Detailed Commit History
Complete chronological analysis for users needing specific technical details.
Click to collapse/expand (33 commits)
Commit 1: 93ae50a - βItem with the same key has already been addedβ Exception fix [CRITICAL]
Date: January 7, 2026
Author: [Author]
Tag: v3.7.1.2
Impact: High - Fixes runtime exception
Changes: - Fixed dictionary key duplication issue causing βItem with the same key has already been addedβ exception - Affected component: Configuration binding or service registration
Reason: Prevented runtime crashes when duplicate keys were encountered
Migration: Automatic - no user action required
Commit 2: fb2b694 - MeterName instead of SpanDurationMeterName
Date: January 7, 2026
Author: [Author]
Tag: v3.7.1.1
Impact: Medium - Configuration property clarification
Changes: - Clarified usage of MeterName vs SpanDurationMeterName properties - SpanDurationMeterName now takes precedence if both are set - Falls back to MeterName if SpanDurationMeterName is not set
Reason: Provides flexibility for users who want to use same meter name for all metrics or specific name for span duration metrics
Migration: Optional - can set either property or both
Commit 3: 5bd7350 - doc fix
Date: January 6, 2026
Author: Dario Airoldi
Impact: None - Documentation only
Changes: Documentation corrections
Commit 4: 368af50 - prompts and changelog update
Date: January 6, 2026
Author: Dario Airoldi
Impact: None - Documentation and tooling
Changes: Updated GitHub Copilot prompts and changelog templates
Commit 5: 47ebed3 - v3.7.1.0 support for multiple metrics filters and enrichers [FEATURE]
Date: January 5, 2026
Author: Dario Airoldi
Tag: v3.7.1.0
Impact: Low - New optional feature
Changes: - Added NamedOptionsMonitor<T> and NamedOptions<T> classes - Added MetricName property to IOptionsBasedMetricRecordingFilterOptions - Added MetricName property to IOptionsBasedMetricRecordingEnricherOptions - Updated OptionsBasedMetricRecordingFilter.ShouldRecord() to accept Instrument parameter - Updated OptionsBasedMetricRecordingEnricher.ExtractTags() to accept Instrument parameter - Added ServiceCollectionCoreExtensions with named options support
Reason: Enables different filtering and enrichment rules per metric instrument
Migration: Optional - existing configurations continue to work. See Migration Guide for adoption
Commit 6: 4a44c25 - quarto style fix
Date: January 5, 2026
Author: Dario Airoldi
Impact: None - Documentation styling
Changes: Fixed Quarto documentation site styling
Commit 7: 4e47521 - doc fix
Date: January 5, 2026
Author: Dario Airoldi
Impact: None - Documentation only
Changes: Documentation corrections
Commit 8: 65a9508 - doc fix
Date: January 5, 2026
Author: Dario Airoldi
Impact: None - Documentation only
Changes: Documentation corrections and additions
Commit 9: 3bd25ca - projects update .net10.0 [FEATURE]
Date: December 1, 2025
Author: Dario Airoldi
Impact: Low - New framework support
Changes: - Added net10.0 to target frameworks in all project files - Updated global.json to SDK version 10.0.100-preview - Regenerated all packages.lock.json files
Reason: Adds support for .NET 10.0 (preview)
Migration: Automatic - packages now support .NET 10.0
Commit 10: 548358f - fix
Date: December 1, 2025
Author: Dario Airoldi
Impact: None - Internal cleanup
Changes: Removed duplicate configuration files (.editorconfig, .gitattributes in src/)
Commit 11: 2b3cff4 - fix
Date: December 1, 2025
Author: Dario Airoldi
Impact: None - Internal cleanup
Changes: Build and configuration fixes
Commit 12: cc26269 - build fix
Date: November 12, 2025
Author: Dario Airoldi
Impact: None - Build system
Changes: Fixed build configuration
Commit 13: a9256cf - changelog
Date: November 12, 2025
Author: Dario Airoldi
Impact: None - Documentation
Changes: Changelog updates
Commit 14: cfded56 - doc fix
Date: November 12, 2025
Author: Dario Airoldi
Impact: None - Documentation
Changes: Documentation fixes
Commit 15: 4f371eb - fix
Date: November 12, 2025
Author: Dario Airoldi
Impact: None - Build system
Changes: Updated _quarto.yml configuration
Commit 16: a46efac - doc update [DOCUMENTATION]
Date: November 12, 2025
Author: Dario Airoldi
Impact: Low - Better documentation
Changes: - Added GitHub Copilot instructions (.github/copilot-instructions.md) - Added documentation templates (.github/templates/) - Added prompts for documentation generation (.github/prompts/) - Added reference documentation: - SpanDurationMetricRecorder.md - OptionsBasedMetricRecordingFilter.md - OptionsBasedMetricRecordingEnricher.md - IDiginsightActivitiesLogOptions.md - IDiginsightActivitiesOptions.md - Updated βCustomize metricsβ to βHow metric recording works with diginsight and Opentelemetryβ
Reason: Improved developer experience and understanding
Migration: No action required - documentation improvements only
Commit 17: 987638c - Fixed Activity and ActivitySource filtering [CRITICAL]
Date: October 10, 2025
Author: Filippo Mineo
Tag: v3.7.0.0 (Final Release)
Impact: High - Critical bug fix
Changes: - Fixed pattern matching logic in OptionsBasedMetricRecordingFilter - Fixed activity source filtering - Fixed wildcard pattern support (e.g., "MyApp.*" now correctly matches)
Before (Broken):
// Patterns like "MyApp.*" sometimes failed to match
// Activity source filtering was inconsistentAfter (Fixed):
// Correct pattern matching:
"MyApp.Orders.*" correctly matches "MyApp.Orders.ProcessOrder"
"MyApp.*" correctly matches all MyApp activitiesReason: Activity filtering patterns were not working as documented
Migration: Automatic - filtering now works correctly
Commit 18: 9cf9421 - Improvements in metric recording
Date: October 8, 2025
Author: Filippo Mineo
Tag: v3.6.0.0-alpha.6
Impact: Medium - Breaking changes
Changes: - Deleted DefaultMetricRecordingEnricherOptions - Renamed IDefaultMetricRecordingEnricherOptions β IOptionsBasedMetricRecordingEnricherOptions - Added OptionsBasedMetricRecordingEnricherOptions implementation - Enhanced OptionsBasedMetricRecordingEnricher configuration binding
Reason: Standardized enricher options naming
Migration: See Migration Guide
Commit 19: 24ce7db - Improvements in metric recording [BREAKING]
Date: October 7, 2025
Author: Filippo Mineo
Tag: v3.6.0.0-alpha.5
Impact: High - Major restructuring
Changes: - File reorganization: Flattened directory structure - Moved files from Extensions/ to root - Moved files from Configurations/ to root - Moved files from Metrics/ to root - Interface renames: - IDiginsightActivitiesSpanDurationOptions β IMetricRecordingOptions - DefaultMetricRecordingEnricher β OptionsBasedMetricRecordingEnricher
Reason: Simplified project structure, consistent naming
Migration: Update interface references (namespaces unchanged)
Commit 20: a664cbb - Improvements in metric recording
Date: October 6, 2025
Author: Filippo Mineo
Tag: v3.6.0.0-alpha.4
Impact: Low - Internal improvements
Changes: - Enhanced SpanDurationMetricRecorder lifecycle management - Improved error handling - Optimized tag collection
Reason: Improved reliability and performance
Migration: Automatic
Commit 21: 35423d8 - Improvements in metric recording
Date: October 5, 2025
Author: Filippo Mineo
Tag: v3.6.0.0-alpha.3
Impact: Medium - Breaking if using deleted interface
Changes: - Deleted ICustomDurationMetricRecorderSettings interface - Enhanced DefaultMetricRecordingEnricher - Optimized OptionsBasedMetricRecordingFilter - Improved SpanDurationMetricRecorder performance - Updated HttpHeadersSpanDurationMetricRecordingFilter
Reason: Removed obsolete interface, improved performance
Migration: If using ICustomDurationMetricRecorderSettings, migrate to IMetricRecordingFilter
Commit 22: af4121c - Rename [BREAKING]
Date: September 25, 2025
Author: Filippo Mineo
Impact: High - Breaking changes
Changes: - Interface renames: - INameBasedMetricRecordingFilterOptions β IOptionsBasedMetricRecordingFilterOptions - Class renames: - NameBasedMetricRecordingFilter β OptionsBasedMetricRecordingFilter - NameBasedMetricRecordingFilterOptions β OptionsBasedMetricRecordingFilterOptions - NameBasedActivityLoggingFilter β OptionsBasedActivityLoggingFilter
Reason: Standardized naming convention
Migration: Update class references and service registrations
Commit 23: dffd6d7 - Fix in DiginsightTextWriter
Date: September 23, 2025
Author: Filippo Mineo
Tag: v3.6.0.0-alpha.2
Impact: Low - Improved log quality
Changes: - Improved character escaping - Better special character handling
Reason: Cleaner log output
Migration: Automatic
Commit 24: e025853 - Fix in DiginsightActivitiesOptions
Date: September 22, 2025
Author: Filippo Mineo
Impact: Low - Reliability improvement
Changes: - Fixed configuration binding issues - Improved default value handling - Cleanup in SpanDurationMetricRecorder and Directory.Build.targets
Reason: Configuration loads correctly
Migration: Automatic
Commit 25: bbdd6cc - small fix
Date: September 21, 2025
Author: Filippo Mineo
Impact: Low - Stability improvement
Changes: - Fixed edge case in DiginsightTextWriter text rendering - Improved null handling
Reason: Fewer exceptions during logging
Migration: Automatic
Commit 26: bab6879 - .sln to .slnx
Date: September 20, 2025
Author: Filippo Mineo
Tag: v3.6.0.0-alpha.1
Impact: None - Build system
Changes: - Updated .github/workflows/v3.yml to use .slnx instead of .sln
Reason: CI/CD workflow update
Migration: No user impact
Commit 27: 9f3896d - .sln to .slnx [INFRASTRUCTURE]
Date: September 20, 2025
Author: Filippo Mineo
Impact: None - Development environment
Changes: - Converted solution file from .sln to .slnx format - Updated Diginsight.slnx structure
Reason: Visual Studio 2022 XML-based solution format
Migration: Visual Studio 2022+ handles both formats automatically
Commit 28: f8f4e9e - Unifying metric recording with filter and enricher [BREAKING]
Date: [Date from git log]
Author: Filippo Mineo
Impact: High - Architecture change
Changes: - Part of metric recording unification - Introduced filter and enricher pattern
Reason: Unified metric recording architecture
Migration: See consolidated migration guide above
Commit 29: c0b4103 - Unifying metric recording with filter and enricher
Date: [Date from git log]
Author: Filippo Mineo
Impact: High - Architecture change
Changes: Continued metric recording unification
Commit 30: 5fa5baa - C# 14 preview. Unifying metric recording with filter and enricher
Date: [Date from git log]
Author: Filippo Mineo
Impact: Medium - Language version update
Changes: - Updated to C# 14 preview features - Continued metric recording unification
Reason: Adopted latest C# features
Migration: No user action - compiler feature
Commit 31: 3bcfd90 - Unifying metric recording with filter and enricher [MAJOR REFACTORING]
Date: [Date from git log]
Author: Filippo Mineo
Impact: High - Major architecture changes
Changes: - Initial implementation of unified metric recording architecture - Introduced IMetricRecordingFilter interface - Introduced IMetricRecordingEnricher interface - Replaced sampler pattern with filter pattern - Changed from IActivityLoggingSampler to IActivityLoggingFilter
Reason: Unified approach to metric recording with better separation of concerns
Migration: See Migration Guide for complete migration steps
Commits 32-33: Additional fixes and improvements
Remaining commits in range include additional minor fixes, documentation updates, and incremental improvements that are consolidated in the changes above.
Document Version: 1.0
Last Updated: January 7, 2026